import React from "react";
import classNames from "classnames";

/**
 * 按钮尺寸枚举
 * 定义按钮的可用尺寸选项
 */
export enum ButtonSize {
  /** 大尺寸按钮 */
  lg = "lg",
  /** 小尺寸按钮 */
  sm = "sm",
}

/**
 * 按钮类型枚举
 * 定义按钮的可用类型选项
 */
export enum ButtonType {
  /** 主要按钮，用于主要操作 */
  primary = "primary",
  /** 默认按钮，用于次要操作 */
  default = "default",
  /** 危险按钮，用于危险操作 */
  danger = "danger",
  /** 链接按钮，外观为链接 */
  link = "link",
}

/**
 * 按钮组件基础属性接口
 * 定义 Button 组件接收的所有属性
 */
interface BaseButtonProps {
  /** 自定义 CSS 类名 */
  className?: string;
  /** 设置按钮是否禁用 */
  disabled?: boolean;
  /** 设置按钮尺寸 */
  size?: ButtonSize;
  /** 设置按钮类型 */
  btnType?: ButtonType;
  /** 按钮内容，可以是文本或 React 节点 */
  children: React.ReactNode;
  /** 链接按钮的 URL 地址（仅对 link 类型有效） */
  href?: string;
}

/**
 * 通用按钮组件
 *
 * 这是一个高度可定制的按钮组件，支持多种类型、尺寸和状态。
 * 组件会根据传入的属性自动生成相应的 CSS 类名。
 *
 * @example
 * ```tsx
 * // 基本使用
 * <Button btnType="primary" size="lg">主要按钮</Button>
 *
 * // 链接按钮
 * <Button btnType="link" href="/about">关于我们</Button>
 *
 * // 禁用状态
 * <Button disabled={true}>禁用按钮</Button>
 * ```
 *
 * @param props - 按钮属性
 * @returns 渲染的按钮或链接元素
 */

/**
 * 原生按钮属性接口
 * 继承 BaseButtonProps 的所有属性，并额外合并了所有标准的 HTML <button> 元素属性。
 * 这使得 Button 组件可以像原生 <button> 一样接收 onClick, onFocus 等事件处理器和属性。
 */
type NativeButtonProps = BaseButtonProps &
  React.ButtonHTMLAttributes<HTMLElement>;
/**
 * 链接按钮属性接口
 * 继承 BaseButtonProps 的所有属性，并额外合并了所有标准的 HTML <a> 元素属性。
 * 这使得 Button 组件在作为链接渲染时，可以接收 href, target 等属性。
 */
type AnchorButtonProps = BaseButtonProps &
  React.AnchorHTMLAttributes<HTMLElement>;
/**
 * 最终导出的 Button 组件属性类型
 * 使用 Partial 工具类型，将 NativeButtonProps 和 AnchorButtonProps 的联合类型的所有属性变为可选。
 * 这样，Button 组件可以灵活地接收原生按钮或链接按钮的任意属性，而无需全部提供。
 */
export type ButtonProps = Partial<NativeButtonProps & AnchorButtonProps>;
export const Button: React.FC<ButtonProps> = (props) => {
  // 解构 props 获取各个属性，并为 btnType 设置默认值为 ButtonType.default
  const {
    btnType = ButtonType.default,
    className,
    disabled,
    size,
    children,
    href,
    ...restProps
  } = props;

  /**
   * 生成按钮的 CSS 类名
   * 使用 classnames 库动态生成类名：
   * - 基础类名: "btn"
   * - 类型类名: "btn-{type}"（如 "btn-primary"）
   * - 尺寸类名: "btn-{size}"（如 "btn-lg"）
   * - 自定义类名: 用户传入的 className
   * - 特殊处理: link 类型的禁用状态
   */
  const classes = classNames("btn", className, {
    [`btn-${btnType}`]: btnType, // 动态生成类型类名
    [`btn-${size}`]: size, // 动态生成尺寸类名
    disabled: btnType === "link" && disabled, // link 类型的禁用样式
  });

  /**
   * 渲染链接按钮
   * 当按钮类型为 link 且提供了 href 时，渲染为 <a> 标签
   */
  if (btnType === "link" && href) {
    return (
      <a
        className={classes}
        href={href}
        {...restProps} // 传递其他属性（如 onClick、aria-label 等）
      >
        {children}
      </a>
    );
  } else {
    /**
     * 渲染普通按钮
     * 对于非 link 类型或没有 href 的 link 类型，渲染为 <button> 标签
     */
    return (
      <button
        className={classes}
        disabled={disabled} // 设置原生 disabled 属性
        {...restProps} // 传递其他属性
      >
        {children}
      </button>
    );
  }
};
